LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use work.dec_pkg.all;

entity dec_top is 
port(
		rst	   :in std_ulogic;
		clk_l 	   :in std_ulogic;               --clk_l low frequency, clk_h high frequency
		clk_r      :in std_ulogic;
		m1_en	   :in std_ulogic;		 --mem1
		cmd1       :in std_ulogic;               --mem1 (wr='1' | rd='0')
		addr1	   :in word16;			 --mem1	
		data1      :in word32;		 	 --mem1	
		ack1       :out std_ulogic;              --mem1
		m2_en	   :in std_ulogic;		 --mem2
		cmd2       :in std_ulogic;               --mem2 (wr='1' | rd='0')
		addr2	   :in word16;			 --mem2	
		data2      :out word16;			 --mem2	
		ack2       :out std_ulogic;              --mem2
		wb_clk    :in std_ulogic;
		wb_en     :in std_ulogic;
		wb_addr   :in word16;
		wb_data   :in word16;
		irq        :out std_ulogic   ;            -- one frame ended (interruption);
		debug_en : in std_ulogic;
    debug_clk : out std_ulogic;
    debug_sel : in std_ulogic;
    debug_data: out std_ulogic_vector(31 downto 0);
		 	
		LKDT       :out std_ulogic;
		
		N     : in std_ulogic_vector(3 downto 0);
		M     : in std_ulogic_vector(6 downto 0);
		OD    : in std_ulogic_vector(1 downto 0);
		BP    : in std_ulogic;		
		PDRST : in std_ulogic
		);
	end dec_top;
	
architecture rtl of dec_top is

   component S65NLLPLLGS_ZP1500 port (
      AVDD : inout std_ulogic;
      AVSS : inout std_ulogic;
      DVDD : inout std_ulogic;
      DVSS : inout std_ulogic;
      XIN : in std_ulogic;
      CLK_OUT : out std_ulogic;
      LKDT : out std_ulogic;
      N : in std_ulogic_vector(3 downto 0);
      M : in std_ulogic_vector(7 downto 1);
      PDRST : in std_ulogic;
      OD : in std_ulogic_vector(1 downto 0);
      BP : in std_ulogic
     
     );
   end component ;
	 component top_control port (
		rst1 : in std_ulogic;
                clk_l : in std_ulogic ;
                clk_h : in std_ulogic;
                sig : out word16;
               -- sel : out std_ulogic;
                cal_len : out frame_length;
                dec_state : in std_ulogic;
                dec_ack : in std_ulogic;
                m1_flag : out std_ulogic;
                m2_flag : out std_ulogic;
                din_addr : out word9;
                dec_req : out std_ulogic;
                dec_end : in std_ulogic;
                 irq2 : out std_ulogic;
                wr_en :  out std_ulogic_vector(7 downto 0);
                rd_en :  out std_ulogic_vector(7 downto 0);
                addr1 : in std_ulogic_vector(15 downto 0);
                cmd1 : in std_ulogic;
                m1_en :in std_ulogic;
                ack12 : out std_ulogic;
                data1 : in word32;
                addr2 : in std_ulogic_vector(15 downto 0);
                m2_en : in std_ulogic;
                cmd2 : in std_ulogic;
                ack22 : out  std_ulogic;
                wb_clk : in std_ulogic;
                wb_en : in std_ulogic;
                wb_addr : in std_ulogic_vector(15 downto 0);
                wb_data : in std_ulogic_vector(15 downto 0);
                dout_addr : out word9 ;
                dout_0 : in word16;
                dout_1 : in word16;
                dout_2 : in word16;
                dout_3 : in word16;
                dout_4 : in word16;
                dout_5 : in word16;
                dout_6 : in word16;
                dout_7 : in word16;
                data13 : out word32;
                data2   : out word16;
                BP : in std_ulogic;
                 lkp    : in std_ulogic;
			           LKDT   : out std_ulogic;
			           rst0   : out std_ulogic
			                   
);

end component;
	 component ram_a
		 port(
			clock1 		:in std_ulogic;
			reset1  	:in std_ulogic;
			write1  	:in std_ulogic;
			read1   	:in std_ulogic;
			en1     	:in std_ulogic;
			data1   	:in word16;
			addr1   	:in std_ulogic_vector(8 downto 0);
			clock2  	:in std_ulogic;
			reset2  	:in std_ulogic;
			write2  	:in std_ulogic;
			read2   	:in std_ulogic;
			en2     	:in std_ulogic;
			data2   	:out word16;
			addr2   	:in std_ulogic_vector(8 downto 0)
			);
	 end component;
	 component ram_f
		 port(
			clock1 		:in std_ulogic;
			reset1  	:in std_ulogic;
			write1  	:in std_ulogic;
			read1   	:in std_ulogic;
			en1     	:in std_ulogic;
			data1   	:in word32;
			addr1   	:in std_ulogic_vector(7 downto 0);
			clock2  	:in std_ulogic;
			reset2  	:in std_ulogic;
			write2  	:in std_ulogic;
			read2   	:in std_ulogic;
			en2     	:in std_ulogic;
			data2   	:out word16;
			addr2   	:in std_ulogic_vector(8 downto 0)
			);
	 end component;
	 
	 component dec_op
		 port(
			clk 		:in std_ulogic;
			rst		:in std_ulogic;
			cal_len : in frame_length;
			state		:out std_ulogic;		        	--idle=0, busy=1
		 	ppin_flag	:in std_ulogic;					--pingpang input
		 	ppout_flag	:in std_ulogic;					--pingpang output
		 	request		:in std_ulogic;
		 	ack		:out std_ulogic;
		 	op_end		:out std_ulogic;
			uin		:in word16_array;
		 	chin		:in word16_array;
		 	sigin		:in word16;
		 	read		:out std_ulogic;
		 --	r_en		:out std_ulogic_vector(7 downto 0);
		 	write		:out std_ulogic;
		 --	w_en		:out std_ulogic_vector(7 downto 0);
		 	addr		:out std_ulogic_vector(8 downto 0);
		 	wb_clk    :in std_ulogic;
      wb_en     :in std_ulogic;
      wb_addr   :in word16;
      wb_data   :in word16;
      debug_en : in std_ulogic;
      debug_clk :out std_ulogic;
      debug_sel : in std_ulogic;
      debug_data: out std_ulogic_vector(31 downto 0);
		 	dout_op		:out word32_array
		     );
	end component;
	 

	
   signal  r_num_temp :bank_num ;

	 -- variable block/frame length
	
	 signal sel:std_ulogic;
	
	 signal m1_flag  	: std_ulogic ;  	                               	
	 signal din_addr  	: word9 ; 
	 signal wr_en		: std_ulogic_vector(7 downto 0);		--wr_en=write enable	 
	 signal temp_addr : std_ulogic_vector(7 downto 0);
	 --cpu reads u & chanx
	 signal m2_flag  	: std_ulogic  ;  	                               	--'0'=high half  '1'=low half
	 signal dout_addr  	: word9 ; 
	           signal   dout_0 :  word16;
             signal dout_1 :  word16;
             signal dout_2 :  word16;
              signal  dout_3 :  word16;
            signal dout_4 :  word16;
            signal dout_5 :  word16;
             signal   dout_6 :  word16;
               signal dout_7 :  word16;
	 signal rd_en		: std_ulogic_vector(7 downto 0);		--wr_en=write enable	 
   signal read_en :std_ulogic;
	 --dec_op reads u&chanx or writes data into ppout
	 signal dec_state	: std_ulogic  ; 
	 signal dec_req,dec_ack : std_ulogic  ; 
	 signal dec_end		: std_ulogic  ; 
	 signal dec_read	: std_ulogic ; 
	 signal dec_write	: std_ulogic ; 
	 signal dec_addr  	: std_ulogic_vector(8 downto 0) ; 
	 signal r_en	  	: std_ulogic_vector(7 downto 0);		--ru_en=read u enable, rch_en=read chanx enable
	 signal w_en  		: std_ulogic_vector(7 downto 0);
	 signal u, ch	: word16_array;
	 signal bin :word32_array;
	 signal sig: word16;
	 signal cal_len:frame_length;
	 signal clk_h : std_ulogic;
   signal lkp,rst0 : std_ulogic;
   signal data13 : word32;
	begin
	  -- temp_addr <= dec_addr(8 downto 1);
     
         dec_con : top_control port map (
				  
                           rst1 => rst,
                           clk_l => clk_l ,
                           clk_h => clk_h ,
                           sig  => sig ,
                           --sel => sel ,
                           cal_len => cal_len,
                           dec_state => dec_state ,
                           dec_ack => dec_ack ,
                           m1_flag => m1_flag ,
                           m2_flag => m2_flag ,
                           din_addr => din_addr,
                           dec_req => dec_req,
                           dec_end => dec_end,
                           irq2     => irq ,
                           wr_en => wr_en ,
                           rd_en => rd_en ,
                           addr1  => addr1,
                           cmd1 => cmd1,
                           m1_en => m1_en ,
                           ack12 => ack1,
			                     data1 => data1,
                           addr2 => addr2,
                           m2_en => m2_en ,
                           cmd2 => cmd2 ,
                           ack22 => ack2,
                           wb_clk => wb_clk ,
                           wb_addr => wb_addr,
                           wb_en => wb_en , 
                           wb_data => wb_data,
			                     dout_addr => dout_addr,
			                     dout_0 => dout_0,
			                     dout_1 => dout_1,
			                     dout_2 => dout_2,
			                     dout_3 => dout_3,
			                     dout_4 => dout_4,
			                     dout_5 => dout_5,
			                     dout_6 => dout_6,
			                     dout_7 => dout_7,
			                     data13 => data13,
			                     lkp => lkp,
			                     LKDT => LKDT ,
			                     BP => BP,
			                     rst0 => rst0,
			                     data2 => data2 
                          );
                           

	 dec_inst: dec_op
		 port map(
				clk 		=> clk_h,
				rst		=> rst0,
				cal_len => cal_len,
				state		=> dec_state,
		 		ppin_flag	=> m1_flag,
		 		ppout_flag	=> m2_flag,
		 		request		=> dec_req,
		 		ack		=> dec_ack,
				op_end		=> dec_end,
				uin		=> u,
		 		chin		=> ch,
		 		sigin		=> sig,
				read		=> dec_read,
			--	r_en		=> r_en,
				write		=> dec_write,
		--		w_en		=> w_en,
		 		addr		=> dec_addr,
		 		wb_clk => wb_clk,
		 		wb_en => wb_en ,
		 		wb_addr =>wb_addr,
		 		wb_data=>wb_data,
		 		debug_clk => debug_clk,
		 		debug_en => debug_en ,
        debug_sel => debug_sel,
        debug_data => debug_data,
		 		dout_op		=> bin
			);


	  --dual-ram instanciation
	  --pingpang input

	  
	   uram1: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(0),
	                     data1  => data13(15 downto 0),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => u(0),
	                     addr2  => dec_addr  );
	  	  
	   uram2: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(1),
	                     data1  => data13(15 downto 0),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => u(1),
	                     addr2  => dec_addr  );
	                     	  
	   uram3: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(2),
	                     data1  => data13(15 downto 0),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => u(2),
	                     addr2  => dec_addr  );
	  	  
	   uram4: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(3),
	                     data1  => data13(15 downto 0),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => u(3),
	                     addr2  => dec_addr  );
	                     	  
	   uram5: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(4),
	                     data1  => data13(15 downto 0),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => u(4),
	                     addr2  => dec_addr  );
	                     	  
	   uram6: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(5),
	                     data1  => data13(15 downto 0),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => u(5),
	                     addr2  => dec_addr  );
	                     	  
	   uram7: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(6),
	                     data1  => data13(15 downto 0),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => u(6),
	                     addr2  => dec_addr  );
	                     	  
	   uram8: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(7),
	                     data1  => data13(15 downto 0),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => u(7),
	                     addr2  => dec_addr  );
	  
	   chram1: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(0),
	                     data1  => data13(31 downto 16),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => ch(0),
	                     addr2  => dec_addr  );
	  chram2: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(1),
	                     data1  => data13(31 downto 16),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => ch(1),
	                     addr2  => dec_addr  );
	      chram3: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(2),
	                     data1  => data13(31 downto 16),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => ch(2),
	                     addr2  => dec_addr  );
	   chram4: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(3),
	                     data1  => data13(31 downto 16),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => ch(3),
	                     addr2  => dec_addr  );
	    chram5: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(4),
	                     data1  => data13(31 downto 16),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => ch(4),
	                     addr2  => dec_addr  );
	     chram6: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(5),
	                     data1  => data13(31 downto 16),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => ch(5),
	                     addr2  => dec_addr  );
	      chram7: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(6),
	                     data1  => data13(31 downto 16),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => ch(6),
	                     addr2  => dec_addr  );
	 chram8: ram_a port map ( clock1 => clk_l,       -- port1  <-> cpu
	                     reset1 => rst0,
	                     write1 => cmd1,
	                     read1  => '0',
	                     en1    => wr_en(7),
	                     data1  => data13(31 downto 16),
	                     addr1  => din_addr,
	                     clock2 => clk_h,       -- port2  <-> decoder
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => dec_read,
	                     en2    => dec_read,
	                     data2  => ch(7),
	                     addr2  => dec_addr  );
	  





	  --  pingpangout=pp_out
	 
	    
	  
	  	    bram1:ram_f port map ( clock1 => clk_h,       -- port1  <-> decoder
	                     reset1 => rst0,
	                     write1 => dec_write,
	                     read1  => '0',
	                     en1    => dec_write, 
	                     data1  => bin(0),
	                     addr1  => dec_addr(8 downto 1),
	                     clock2 => clk_l,       -- port2  <-> cpu
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => cmd2,
	                     en2    => rd_en(0),
	                     data2  => dout_0,
	                     addr2  => dout_addr  );
	      bram2:ram_f port map ( clock1 => clk_h,       -- port1  <-> decoder
	                     reset1 => rst0,
	                     write1 => dec_write,
	                     read1  => '0',
	                     en1    => dec_write, 
	                     data1  => bin(1),
	                     addr1  => dec_addr(8 downto 1),
	                     clock2 => clk_l,       -- port2  <-> cpu
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => cmd2,
	                     en2    => rd_en(1),
	                     data2  => dout_1,
	                     addr2  => dout_addr  );
         bram3:ram_f port map ( clock1 => clk_h,       -- port1  <-> decoder
	                     reset1 => rst0,
	                     write1 => dec_write,
	                     read1  => '0',
	                     en1    => dec_write, 
	                     data1  => bin(2),
	                     addr1  => dec_addr(8 downto 1),
	                     clock2 => clk_l,       -- port2  <-> cpu
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => cmd2,
	                     en2    => rd_en(2),
	                     data2  => dout_2,
	                     addr2  => dout_addr  );
	       bram4:ram_f port map ( clock1 => clk_h,       -- port1  <-> decoder
	                     reset1 => rst0,
	                     write1 => dec_write,
	                     read1  => '0',
	                     en1    => dec_write, 
	                     data1  => bin(3),
	                     addr1  => dec_addr(8 downto 1),
	                     clock2 => clk_l,       -- port2  <-> cpu
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => cmd2,
	                     en2    => rd_en(3),
	                     data2  => dout_3,
	                     addr2  => dout_addr  );
	      bram5:ram_f port map ( clock1 => clk_h,       -- port1  <-> decoder
	                     reset1 => rst0,
	                     write1 => dec_write,
	                     read1  => '0',
	                     en1    => dec_write, 
	                     data1  => bin(4),
	                     addr1  => dec_addr(8 downto 1),
	                     clock2 => clk_l,       -- port2  <-> cpu
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => cmd2,
	                     en2    => rd_en(4),
	                     data2  => dout_4,
	                     addr2  => dout_addr  );
	     bram6:ram_f port map ( clock1 => clk_h,       -- port1  <-> decoder
	                     reset1 => rst0,
	                     write1 => dec_write,
	                     read1  => '0',
	                     en1    => dec_write, 
	                     data1  => bin(5),
	                     addr1  => dec_addr(8 downto 1),
	                     clock2 => clk_l,       -- port2  <-> cpu
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => cmd2,
	                     en2    => rd_en(5),
	                     data2  => dout_5,
	                     addr2  => dout_addr  );
	     bram7:ram_f port map ( clock1 => clk_h,       -- port1  <-> decoder
	                     reset1 => rst0,
	                     write1 => dec_write,
	                     read1  => '0',
	                     en1    => dec_write, 
	                     data1  => bin(6),
	                     addr1  => dec_addr(8 downto 1),
	                     clock2 => clk_l,       -- port2  <-> cpu
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => cmd2,
	                     en2    => rd_en(6),
	                     data2  => dout_6,
	                     addr2  => dout_addr  );
      bram8:ram_f port map ( clock1 => clk_h,       -- port1  <-> decoder
	                     reset1 => rst0,
	                     write1 => dec_write,
	                     read1  => '0',
	                     en1    => dec_write, 
	                     data1  => bin(7),
	                     addr1  => dec_addr(8 downto 1),
	                     clock2 => clk_l,       -- port2  <-> cpu
	                     reset2 => rst0,
	                     write2 => '0',
	                     read2  => cmd2,
	                     en2    => rd_en(7),
	                     data2  => dout_7,
	                     addr2  => dout_addr  );
  pll :   S65NLLPLLGS_ZP1500 port map(
      
      XIN => clk_r,
      CLK_OUT => clk_h,
      N => N,
      M =>M,
      PDRST => PDRST,
      OD => OD,
      BP => BP,
      LKDT => lkp
     );
   

------------------------------------------------------------------------------------------------------	  
------------------------------------------------------------------------------------------------------
     end rtl;
